package com.fan.tank;

import com.fan.game.Bullet;
import com.fan.game.Explode;
import com.fan.game.GameFrame;
import com.fan.util.*;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 坦克类
 */
public abstract class Tank {
    //四个方向
    public static final int DIR_UP = 0;
    public static final int DIR_DOWN = 1;
    public static final int DIR_LEFT = 2;
    public static final int DIR_RIGHT = 3;

    //半径
    public static final int RADIUS = 20;

    //默认速度  每帧的速度
    private static final int DEFAULT_SPEED = 6;

    //坦克的状态
    public static final int STATE_STAND = 0;
    public static final int STATE_MOVE = 1;
    public static final int STATE_DIE = 2;

    //坦克的初始生命
    public static final int DEFAULT_HP = 1000;

    //初始坐标
    private int x,y;

    //名字
    private String name;

    //血量
    private int hp = DEFAULT_HP;

    //速度
    private int speed = DEFAULT_SPEED;

    //攻击力
    private int atk;

    //伤害的区间
    private static final int ATK_MAX = 100;
    private static final int ATK_MIN = 50;

    //方向
    private int dir ;

    //状态
    private int state = STATE_STAND;

    //颜色
    private Color color;

    //标识
    private Boolean isEnemy = false;
    //创建一个血条对象
    private BloodBar bar = new BloodBar();

    //TODO 炮弹
  private List<Bullet> bullets = new ArrayList();

    //使用容器当前坦克上所有的爆炸效果
    private List<Explode> explodes = new ArrayList<>();

    //创建自己的坦克
    public Tank(int x, int y, int dir) {
        this.x = x;
        this.y = y;
        this.dir = dir;
        initTank();
    }

    public Tank() {
        initTank();
    }
    private void initTank(){
        color = MyUtil.getRandomColor();
        name = MyUtil.getRandomName();
        atk = MyUtil.getRandomNumber(ATK_MIN,ATK_MAX);
    }
    //创建一个敌人的坦克



    /**
     * 坦克的绘制
     */

    public void draw(Graphics g){

        logic();
        
        drawImgTank(g);
        
        drawBullets(g);

        drawName(g);

        bar.draw(g);



        
    }

    private void drawName(Graphics g){
        g.setColor(color);
        g.setFont(Constant.SMALL_font);
        g.drawString(name,x - RADIUS,y - 40);

    }

    /**
     * 使用图片的方式绘制
     */
    public abstract void drawImgTank(Graphics g);

    /**
     * 使用系统的方式绘制坦克
     * @param g
     */
    private void drawTank(Graphics g){
        g.setColor(color);
        //绘制圆
        g.fillOval(x-RADIUS,y-RADIUS,RADIUS<<1,RADIUS<<1);

        //绘制炮筒
        int endX = x;
        int endY = y;
        switch (dir){
            case DIR_UP:
                endY = y-2*RADIUS;
                g.drawLine(x-1,y,endX-1,endY);
                g.drawLine(x+1,y,endX+1,endY);
                break;
            case DIR_DOWN:
                endY = y+2*RADIUS;
                g.drawLine(x-1,y,endX-1,endY);
                g.drawLine(x+1,y,endX+1,endY);
                break;
            case DIR_LEFT:
                endX = x-2*RADIUS;
                g.drawLine(x,y-1,endX,endY-1);
                g.drawLine(x,y+1,endX,endY+1);
                break;
            case DIR_RIGHT:
                endX = x+2*RADIUS;
                g.drawLine(x,y-1,endX,endY-1);
                g.drawLine(x,y+1,endX,endY+1);
                break;
        }
        g.drawLine(x,y,endX,endY);
    }



    //坦克的逻辑处理
    private void logic(){
        switch (state){
            case STATE_STAND:
                break;
            case STATE_MOVE:
                move();
                break;
            case STATE_DIE:
                break;
        }
    }

    //坦克移动的功能
    private  void move(){
        switch (dir){
            case DIR_UP:
                y -=speed;
                if(y < RADIUS + GameFrame.titleBarh){
                    y = RADIUS + GameFrame.titleBarh;
                }
                break;
            case DIR_DOWN:
                y += speed;
                if(y> Constant.FRAME_HEIGHT-RADIUS){
                    y = Constant.FRAME_HEIGHT-RADIUS;
                }
                break;
            case  DIR_LEFT:
                x -=speed;
                if(x < RADIUS){
                    x = RADIUS;
                }
                break;
            case DIR_RIGHT:
                x +=speed;
                if(x > Constant.FRAME_WIDTH-RADIUS){
                    x = Constant.FRAME_WIDTH-RADIUS;
                }
                break;
        }
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getDir() {
        return dir;
    }

    public void setDir(int dir) {
        this.dir = dir;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public List getBullets() {
        return bullets;
    }

    public void setBullets(List bullets) {
        this.bullets = bullets;
    }

    public boolean isEnemy(){
        return isEnemy;
    }

    public void setEnemy(Boolean enemy) {
        isEnemy = enemy;
    }

    //public String getName() {
    //    return name;
    //}

    //public void setName(String name) {
     //   this.name = name;
    //}

    @Override
    public String toString() {
        return "Tank{" +
                "x=" + x +
                ", y=" + y +
                ", hp=" + hp +
                ", speed=" + speed +
                ", atk=" + atk +
                ", dir=" + dir +
                ", state=" + state +
                ", color=" + color +
                ", bullets=" + bullets +
                '}';
    }


    /**
     * 开火方法
     */
    public void fire(){
        int bulletx = x;
        int bullrty = y;
        switch (dir){
            case DIR_UP:
                bullrty -= RADIUS;
                break;
            case DIR_DOWN:
                bullrty += RADIUS;
                break;
            case DIR_LEFT:
                bulletx -= RADIUS;
                break;
            case DIR_RIGHT:
                bulletx += RADIUS;
                break;
        }

        Bullet bullet = BulletsPool.get();
        bullet.setX(bulletx);
        bullet.setY(bullrty);
        bullet.setDir(dir);
        bullet.setAtk(atk);
        bullet.setColor(color);
        bullet.setVisible(true);
        bullets.add(bullet);
    }

    /**
     * 将当前坦克所有子弹绘制出来
     * @param g
     */
    private void drawBullets(Graphics g){
        for(Bullet bullet:bullets){
            bullet.draw(g);
        }
        //便利所有的子弹，将不可见的子弹移除归还到池塘里
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            if(!bullet.isVisible()){
                Bullet remove = bullets.remove(i);
                BulletsPool.theReturn(remove);
            }
        }
    }

    //坦克和敌人的子弹碰撞的方法
    public void collideBullets(List<Bullet> bullets){
        for (Bullet bullet : bullets) {
            int bulletX = bullet.getX();
            int bulletY = bullet.getY();
            if( MyUtil.isCollide(x,y,RADIUS,bulletX,bulletY)){
                //子弹和坦克碰上了
                   //子弹要消失
                bullet.setVisible(false);



                   //添加爆炸效果
                Explode explode = ExplodePool.get();

                explode.setX(x);
                explode.setY(y + RADIUS);
                explode.setVisible(true);
                explode.setIndex(0);
                explodes.add(explode);
                   //坦克收到伤害
                hurt(bullet);
            }
        }

    }
    /**
     * 坦克受到伤害的方法
     */
     private void hurt(Bullet bullet){
         int atk = bullet.getAtk();
         hp -= atk;
         if(hp<0){
             hp = 0;
             die();
         }
     }


     //坦克死亡需要做的内容
     private void die(){
         if(isEnemy){
             //todo 敌人坦克被消灭,归还到对象池
             EnemyTanksPool.theReturn(this);
         }else {
             //gameover todo
             //自己死了，切换游戏状态
             GameFrame.setGameState(Constant.STATE_OVER);
         }

     }

     public boolean isDie(){
         return hp <= 0;
     }


    /**
     * 绘制一个坦克所有的爆炸效果
     */
    public void drawExplode(Graphics g){
        for(Explode explode : explodes){
            explode.draw(g);
        }
        //将不可见的爆炸效果归还
        for (int i = 0; i < explodes.size(); i++) {
            Explode explode = explodes.get(i);
            if(!explode.isVisible()){
                Explode remove = explodes.remove(i);
                ExplodePool.theReturn(remove);
                i--;
            }
        }
    }

    //内部类
    class BloodBar{
        public static final int BAR_LENGTH = 50;
        public static final int BAR_HEIGHT = 5;

        public void draw(Graphics g){
            //填充底色
            g.setColor(Color.yellow);
            g.fillRect(x-RADIUS,y - RADIUS - BAR_HEIGHT*2,BAR_LENGTH,BAR_HEIGHT);
            //红色的血条
            g.setColor(Color.RED);
            g.fillRect(x - RADIUS,y-RADIUS-BAR_HEIGHT*2,hp*BAR_LENGTH/DEFAULT_HP,BAR_HEIGHT);
            //蓝色的边框
            g.setColor(Color.WHITE);
            g.drawRect(x-RADIUS,y - RADIUS - BAR_HEIGHT*2,BAR_LENGTH,BAR_HEIGHT);

        }
    }

}
